﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using TakePhotoTogether.Communication.Protocols;

namespace TakePhotoTogether.Communication
{
    public class RemoteSemaphore
    {
        private static bool internalSemaphore = false;
        private static RemoteSemaphoreListener semaphoreListener = new RemoteSemaphoreListener();

        public static bool HasToken()
        {
            return internalSemaphore;
        }

        public static bool Request()
        {
            if (internalSemaphore)
            {
                return internalSemaphore;
            }

            semaphoreListener.OnRequestAccepted = () =>
                {
                    internalSemaphore = true;
                };

            DataPacket requestPacket = DataPacketFactory.GetResourceLockingPacket(LockingMessage.Request);
            SocketManager.GetSocketManager().SendData(requestPacket);

            return false;
        }

        public static void Release()
        {
            if (internalSemaphore)
            {
                internalSemaphore = false;

                DataPacket requestPacket = DataPacketFactory.GetResourceLockingPacket(LockingMessage.Release);
                SocketManager.GetSocketManager().SendData(requestPacket);

            }

        }
    }

    class RemoteSemaphoreListener : IRemoteDataListener
    {
        public Action OnRequestAccepted = null;

        public RemoteSemaphoreListener()
        {
            SocketManager.GetSocketManager().AddDataListener(this, (int)MessageTypes.ResourceLockingPacket);

            Debug.WriteLine("RemoteSemaphoreListener - Added itself as an IRemoteDataListener");
        }

        public void ReceiveData(PayloadData data)
        {
            if (data is LockingData)
            {
                LockingMessage message = (LockingMessage)((LockingData)data).Message;

                if (message == LockingMessage.Request)
                {
                    DataPacket answer = null;

                    if (RemoteSemaphore.HasToken())
                    {
                        answer = DataPacketFactory.GetResourceLockingPacket(LockingMessage.Denied_Request);
                    }
                    else
                    {
                        answer = DataPacketFactory.GetResourceLockingPacket(LockingMessage.Accepted_Request);
                    }

                    SocketManager.GetSocketManager().SendData(answer);
                }
                else if (message == LockingMessage.Accepted_Request)
                {
                    if (OnRequestAccepted != null)
                    {
                        OnRequestAccepted();
                    }
                }
            }
        }
    }
}
